import { BetRecordEmpty } from "@/pages/BetRecordPage/components/BetRecordEmpty"
import styled from "@emotion/styled"
import { useDebounceFn } from "ahooks"
import React, { forwardRef, Fragment } from "react"
import { GridComponents, VirtuosoGrid } from "react-virtuoso"
import { LoadSummary } from "./LoadSummary"

interface GridProps<D extends object> {
    style?: React.CSSProperties
    height: number | string
    list: D[]
    isLoading?: boolean
    emptyText?: string
    itemContent: (idx: number, row: D) => React.ReactNode
    onLoadMore?: () => void
}

type VirtuosoGridContext<D extends object> = Omit<
    GridProps<D>,
    "onLoadMore" | "height" | "itemContent"
>

const GridItem = styled.div`
    width: 33.333333%;
    display: flex;
    flex: none;
    align-content: stretch;
    box-sizing: "border-box";
    padding: 6rem 3rem;
`

const GridList = styled.div`
    display: flex;
    flex-wrap: wrap;
`

const Container = styled.div`
    padding-left: 9rem;
    padding-right: 9rem;
`
const gridComponents: GridComponents = {
    List: forwardRef<HTMLDivElement, React.HtmlHTMLAttributes<HTMLDivElement>>(
        ({ children, style, ...props }, ref) => (
            <GridList
                ref={ref}
                {...props}
                style={style}
                children={children}
            />
        ),
    ),
    Item: forwardRef<HTMLDivElement, React.HtmlHTMLAttributes<HTMLDivElement>>(
        ({ children, ...props }, ref) => (
            <GridItem
                ref={ref}
                {...props}
                children={children}
            />
        ),
    ),
    Footer: ({ context = {} }) => {
        return (
            <LoadSummary
                isLoading={context.isLoading}
                count={context.list.length}
            />
        )
    },
}

export function GridGameList<D extends object>({
    height = 400,
    list = [],
    isLoading = false,
    emptyText = "",
    itemContent = () => <Fragment />,
    onLoadMore,
}: GridProps<D>) {
    const { run: loadMoreDebounced } = useDebounceFn(
        () => {
            if (!isLoading) {
                onLoadMore?.()
            }
        },
        {
            wait: 300,
        },
    )

    if (!isLoading && list.length === 0) {
        return <BetRecordEmpty desc={emptyText} />
    }
    return (
        <Container>
            <VirtuosoGrid<D, VirtuosoGridContext<D>>
                style={{ height }}
                context={{
                    isLoading,
                    list,
                    emptyText,
                }}
                totalCount={list.length}
                components={gridComponents}
                itemContent={(idx: number) => {
                    const row = list[idx]
                    return itemContent(idx, row)
                }}
                endReached={loadMoreDebounced}
            />
        </Container>
    )
}
